home *** CD-ROM | disk | FTP | other *** search
/ CICA 1993 April / CICA MS Windows - April 1993.iso / unzipped / programr / toolbar / toolbar.c < prev    next >
C/C++ Source or Header  |  1992-06-26  |  10KB  |  405 lines

  1. /*+
  2.  *
  3.  *  Module:
  4.  *        Toolbar
  5.  *
  6.  *  Description:
  7.  *        General toolbar functions
  8.  *
  9.  *  Original author:
  10.  *        Stephen Chung
  11.  *
  12.  *  Copyright (C) Stephen Chung, 1991.  All rights reserved.
  13. -*/
  14.  
  15. #include <windows.h>
  16. #include "toolbar.h"
  17.  
  18. #define MAXSTATES       3
  19.  
  20. static BOOL ClassRegistered = FALSE;
  21. static BOOL Capturing = FALSE;
  22.  
  23. long FAR PASCAL ToolbarProc (HWND, WORD, WORD, LONG);
  24. long FAR PASCAL ToolbarButtonProc (HWND, WORD, WORD, LONG);
  25.  
  26.  
  27. void Create3DEffect (HDC hdc, RECT *rect, int thickness, int style)
  28. {
  29.     int     i;
  30.     int     x1 = rect->left;
  31.     int     y1 = rect->top;
  32.     int     x2 = rect->right;
  33.     int     y2 = rect->bottom;
  34.  
  35.     HBRUSH  hbrush, oldbrush;
  36.     HPEN    hpen, oldpen;
  37.  
  38.     oldpen = SelectObject(hdc, GetStockObject(BLACK_PEN));
  39.     switch (style)
  40.     {
  41.         default:
  42.         case 0:
  43.         case 1: hbrush = GetStockObject(LTGRAY_BRUSH); break;
  44.         case 2: hbrush = GetStockObject(WHITE_BRUSH); break;
  45.     }
  46.  
  47.     oldbrush = SelectObject(hdc, hbrush);
  48.     Rectangle(hdc, x1, y1, x2, y2);
  49.  
  50.     switch(style)
  51.     {
  52.       default:
  53.       case 0:  SelectObject(hdc, GetStockObject(WHITE_PEN)); break;
  54.       case 1:  hpen = CreatePen(PS_SOLID, 1, RGB(128, 128, 128));
  55.                SelectObject(hdc, hpen);
  56.                break;
  57.       case 2:  SelectObject(hdc, GetStockObject(BLACK_PEN)); break;
  58.     }
  59.  
  60.     for (i = 1; i <= thickness; i++)
  61.     {
  62.         MoveTo(hdc, x1 + i, y1 + i);    LineTo(hdc, x1 + i, y2 - 1);
  63.         MoveTo(hdc, x1 + i, y1 + i);    LineTo(hdc, x2 - 1, y1 + i);
  64.     }
  65.  
  66.     switch (style)
  67.     {
  68.         default:
  69.         case 0:
  70.         case 2:
  71.           hpen = CreatePen(PS_SOLID, 1, RGB(128,128,128));
  72.           SelectObject(hdc, hpen);
  73.           break;
  74.         case 1:
  75.           SelectObject(hdc, GetStockObject(WHITE_PEN)); break;
  76.     }
  77.  
  78.     for (i = 1; i <= thickness; i++)
  79.     {
  80.         MoveTo(hdc, x1 + i, y2 - 1 - i);
  81.         LineTo(hdc, x2 - 1, y2 - 1 - i);
  82.         MoveTo(hdc, x2 - 1 - i, y2 - 2);
  83.         LineTo(hdc, x2 - 1 - i, y1 + i);
  84.     }
  85.  
  86.     SelectObject(hdc, oldbrush);
  87.     SelectObject(hdc, oldpen);
  88.  
  89.     DeleteObject(hpen);
  90. }
  91.  
  92. static void CursorShape(HWND hwnd, int state)
  93. {
  94.     HCURSOR hcursor;
  95.     static HCURSOR arrow = NULL;
  96.  
  97.     if (state < 0)
  98.        hcursor = (HCURSOR) GetWindowWord(GetParent(hwnd), 3 * sizeof(WORD));
  99.     else
  100.     if (arrow == NULL)
  101.        hcursor = arrow = LoadCursor(NULL, IDC_ARROW);
  102.     else
  103.        hcursor = arrow;
  104.  
  105.     SetCursor(hcursor);
  106. }
  107.  
  108. void EnableToolbarButton (HWND hwnd, int id, BOOL enabled)
  109. {
  110.     int             i, n;
  111.     TOOLBARICON     *icons;
  112.  
  113.     icons = (TOOLBARICON *) GetWindowWord(hwnd, 0);
  114.     n = (int) GetWindowWord(hwnd, sizeof(WORD));
  115.  
  116.     for (i = 0; i < n && icons[i].id != id; i++);
  117.  
  118.     if (i >= n) return;
  119.  
  120.     if (enabled) {
  121.         if (icons[i].state >= 0) return;
  122.         icons[i].state = icons[i].oldstate;
  123.     } else {
  124.         if (icons[i].state < 0) return;
  125.         icons[i].oldstate = icons[i].state;
  126.         icons[i].state = -1;
  127.     }
  128.     InvalidateRect(icons[i].hwnd, NULL, FALSE);
  129.         UpdateWindow(icons[i].hwnd);
  130. }
  131.  
  132. HWND GetToolbarButton (HWND hwnd, int id, TOOLBARICON *ip)
  133. {
  134.     int             i, n;
  135.     TOOLBARICON     *icons;
  136.  
  137.     icons = (TOOLBARICON *) GetWindowWord(hwnd, 0);
  138.     n = (int) GetWindowWord(hwnd, sizeof(WORD));
  139.  
  140.     for (i = 0; i < n && icons[i].id != id; i++);
  141.  
  142.         if (i >= n) return (NULL);
  143.  
  144.         if (ip != NULL) *ip = icons[i];
  145.  
  146.         return (icons[i].hwnd);
  147. }
  148.  
  149.  
  150.  
  151. void ModifyToolbarButton (HWND hwnd, TOOLBARICON *icon)
  152. {
  153.     TOOLBARICON *old;
  154.  
  155.     old = (TOOLBARICON *) GetWindowWord(hwnd, 0);
  156.  
  157.     old->id = icon->id;
  158.     old->x = icon->x;
  159.     old->y = icon->y;
  160.     old->width = icon->width;
  161.     old->height = icon->height;
  162.     old->state = icon->state;
  163.     old->cycle = icon->cycle;
  164.     old->disabled = icon->disabled;
  165.     old->undepressed = icon->undepressed;
  166.     old->depressed = icon->depressed;
  167.     old->grayed = icon->grayed;
  168.     old->pressing = icon->pressing;
  169.  
  170.     InvalidateRect(hwnd, NULL, TRUE);
  171.     UpdateWindow(hwnd);
  172. }
  173.  
  174.  
  175.  
  176. HWND CreateToolbar (HWND parent, int x, int y, int width, int height,
  177.                     int thickness, int id, int n, HANDLE hInstance,
  178.                     TOOLBARICON *icons, char *xcursor)
  179. {
  180.     int         i;
  181.     HWND        hwnd;
  182.     WNDCLASS    wndclass;
  183.  
  184.     if (!ClassRegistered) {
  185.         wndclass.style          = CS_HREDRAW | CS_VREDRAW;
  186.         wndclass.lpfnWndProc    = ToolbarProc;
  187.         wndclass.cbClsExtra     = 0;
  188.         wndclass.cbWndExtra     = 4 * sizeof(WORD);
  189.         wndclass.hInstance      = hInstance;
  190.         wndclass.hIcon          = LoadIcon(NULL, IDI_APPLICATION);
  191.         wndclass.hCursor        = LoadCursor(NULL, IDC_ARROW);
  192.         wndclass.hbrBackground  = COLOR_BTNFACE + 1;
  193.         wndclass.lpszMenuName   = NULL;
  194.         wndclass.lpszClassName  = TOOLBARCLASS;
  195.  
  196.         RegisterClass(&wndclass);
  197.  
  198.         wndclass.cbWndExtra     = sizeof(WORD);
  199.         wndclass.lpfnWndProc    = ToolbarButtonProc;
  200.         wndclass.lpszClassName  = TOOLBARBUTTONCLASS;
  201.  
  202.         RegisterClass(&wndclass);
  203.     }
  204.  
  205.     hwnd = CreateWindow(TOOLBARCLASS, "", WS_CHILD /* | WS_VISIBLE */ ,
  206.                         x, y, width, height, parent, id, hInstance, NULL);
  207.  
  208.     SetWindowWord(hwnd, 0, (WORD) icons);
  209.     SetWindowWord(hwnd, sizeof(WORD), (WORD) n);
  210.     SetWindowWord(hwnd, 2 * sizeof(WORD), (WORD) thickness);
  211.     if (xcursor != NULL)
  212.     {
  213.         SetWindowWord(hwnd, 3 * sizeof(WORD), LoadCursor(hInstance, xcursor));
  214.     }
  215.     else
  216.     {
  217.         SetWindowWord(hwnd, 3 * sizeof(WORD), NULL);
  218.     }
  219.  
  220.     //ShowWindow(hwnd, SW_SHOW);
  221.     //UpdateWindow(hwnd);
  222.  
  223.     /* Create the children */
  224.  
  225.     for (i = 0; i < n; i++)
  226.     {
  227.         icons[i].hwnd = CreateWindow(TOOLBARBUTTONCLASS, "",
  228.                                      WS_CHILD | WS_VISIBLE,
  229.                                      icons[i].x, icons[i].y,
  230.                                      icons[i].width, icons[i].height,
  231.                                      hwnd, icons[i].id, hInstance, NULL);
  232.  
  233.         SetWindowWord(icons[i].hwnd, 0, (WORD) &(icons[i]));
  234.         ShowWindow(icons[i].hwnd, SW_SHOW);
  235.         UpdateWindow(hwnd);
  236.     }
  237.  
  238.     return (hwnd);
  239. }
  240.  
  241. long FAR PASCAL _export ToolbarProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
  242. {
  243.     int             i;
  244.     HDC             hdc;
  245.     PAINTSTRUCT     ps;
  246.     HWND            child;
  247.     RECT            rect;
  248.     TOOLBARICON     *icons;
  249.  
  250.  
  251.     switch (message) {
  252.  
  253.         case WM_PAINT:
  254.             GetClientRect(hwnd, &rect);
  255.  
  256.             hdc = BeginPaint(hwnd, &ps);
  257.             Create3DEffect(hdc, &rect, GetWindowWord(hwnd, 2 * sizeof(WORD)), 0);
  258.             EndPaint(hwnd, &ps);
  259.             return (0);
  260.  
  261.         case WM_COMMAND:
  262.             SendMessage(GetParent(hwnd), WM_COMMAND,
  263.                         (wParam << 8) | GetWindowWord(hwnd, GWW_ID), lParam);
  264.             return (0);
  265.  
  266.         case BM_SETSTATE:
  267.         case BM_GETSTATE:
  268.             icons = (TOOLBARICON *) GetWindowWord(hwnd, 0);
  269.             for (i = 0; icons[i].id != LOWORD(lParam); i++);
  270.             return (SendMessage(icons[i].hwnd, message, wParam, 0L));
  271.     }
  272.  
  273.     return (DefWindowProc(hwnd, message, wParam, lParam));
  274. }
  275.  
  276.  
  277.  
  278. long FAR PASCAL _export ToolbarButtonProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
  279. {
  280.     int             i, j;
  281.     BOOL            crossed;
  282.     HDC             hdc, hdcmem;
  283.     PAINTSTRUCT     ps;
  284.     HPEN            hpen;
  285.     HWND            child;
  286.     TOOLBARICON     *icon;
  287.     HBITMAP         hbitmap;
  288.     HANDLE            hInstance;
  289.     HCURSOR         hcursor;
  290.  
  291.  
  292.     icon = (TOOLBARICON *) GetWindowWord(hwnd, 0);
  293.  
  294.     switch (message)
  295.     {
  296.  
  297.       case BM_SETSTATE:
  298.         if (icon->state == wParam) return (0);
  299.  
  300.         icon->oldstate = icon->state = wParam;
  301.         InvalidateRect(hwnd, NULL, FALSE);
  302.         UpdateWindow(hwnd);
  303.         return (0);
  304.  
  305.     case BM_GETSTATE:
  306.         return (icon->state);
  307.  
  308.     case WM_LBUTTONDOWN:
  309.         if (icon->state < 0) return (0);
  310.  
  311.         icon->oldstate = icon->state;
  312.         icon->state = MAXSTATES;
  313.         InvalidateRect(hwnd, NULL, FALSE);
  314.         UpdateWindow(hwnd);
  315.         SetCapture(hwnd);
  316.         Capturing = TRUE;
  317.         return (0);
  318.  
  319.     case WM_LBUTTONUP:
  320.         if (!Capturing || icon->state < 0) return (0);
  321.  
  322.         ReleaseCapture();
  323.         Capturing = FALSE;
  324.  
  325.         i = LOWORD(lParam);
  326.         j = HIWORD(lParam);
  327.  
  328.         if (i < 0 || i >= icon->width || j < 0 || j >= icon->height) {
  329.             return (0);
  330.         } else if (icon->cycle <= 0) {
  331.             icon->state = icon->oldstate;
  332.         } else {
  333.             icon->oldstate++;
  334.             if (icon->oldstate >= icon->cycle) icon->oldstate = 0;
  335.             icon->state = icon->oldstate;
  336.         }
  337.  
  338.         InvalidateRect(hwnd, NULL, FALSE);
  339.         UpdateWindow(hwnd);
  340.         CursorShape(hwnd, icon->state);
  341.         SendMessage(GetParent(hwnd), WM_COMMAND, icon->id, MAKELONG(hwnd, BN_CLICKED));
  342.         return (0);
  343.  
  344.     case WM_MOUSEMOVE:
  345.         CursorShape(hwnd, icon->state);
  346.         if (!Capturing || icon->state < 0) return (0);
  347.  
  348.         i = LOWORD(lParam);
  349.         j = HIWORD(lParam);
  350.  
  351.         if (i < 0 || i >= icon->width || j < 0 || j >= icon->height)
  352.         {
  353.             crossed = (icon->state == MAXSTATES);
  354.             icon->state = icon->oldstate;
  355.         } else
  356.         {
  357.             crossed = (icon->state != MAXSTATES);
  358.             icon->state = MAXSTATES;
  359.         }
  360.  
  361.         if (crossed)
  362.         {
  363.             InvalidateRect(hwnd, NULL, FALSE);
  364.             UpdateWindow(hwnd);
  365.         }
  366.         return (0);
  367.  
  368.     case WM_PAINT:
  369.         hInstance = GetWindowWord(hwnd, GWW_HINSTANCE);
  370.  
  371.         hdc = BeginPaint(hwnd, &ps);
  372.  
  373.         switch (icon->state) {
  374.             default: if (icon->disabled != NULL)
  375.             {
  376.                     hbitmap = LoadBitmap(hInstance, icon->disabled);
  377.             }
  378.             break;
  379.  
  380.             case 0:  hbitmap = LoadBitmap(hInstance, icon->undepressed); break;
  381.             case 1:  hbitmap = LoadBitmap(hInstance, icon->depressed); break;
  382.             case 2:  hbitmap = LoadBitmap(hInstance, icon->grayed); break;
  383.  
  384.             case MAXSTATES:
  385.                     hbitmap = LoadBitmap(hInstance, icon->pressing); break;
  386.         }
  387.  
  388.         hdcmem = CreateCompatibleDC(hdc);
  389.         SelectObject(hdcmem, hbitmap);
  390.  
  391.         BitBlt(hdc, 0, 0, icon->width, icon->height, hdcmem, 0, 0, SRCCOPY);
  392.  
  393.         if (!DeleteDC(hdcmem))
  394.            MessageBox(NULL, "TOOLBAR: Could not delete DC", "DeleteDC error",
  395.                         MB_ICONEXCLAMATION | MB_OK);
  396.         if (!DeleteObject(hbitmap))
  397.            MessageBox(NULL, "TOOLBAR: Could not delete bitmapC", "DeleteObject error",
  398.                         MB_ICONEXCLAMATION | MB_OK);
  399.         EndPaint(hwnd, &ps);
  400.         return (0);
  401.     }
  402.  
  403.     return (DefWindowProc(hwnd, message, wParam, lParam));
  404. }
  405.